#include "vic.h"
#include "app.h"
#include "uart0_irq.h"

void showVicError(int n) {
	par_ValuesDefaults();
	flash_Save();
	flash_SaveLogError(control.ticks, n);

	// Filtra erro para exibição para usuário via led erro
	if (n < 100) n = 1; 					// erro de sistema
	else if (n==errCRC_FLASH) n=2;			// erro CRC da flash parametros
	else if (n==errSERVO_PAR_OFFSET) n=3;
	else if (n==errSERVO_PAR_INIT) n=4;
	else if (n==errSERVO_PAR_MIM) n=5;
	else if (n==errSERVO_PAR_MAX) n=6;
	else if (n==errSERVO_PAR_TIME_PROGRESS) n=7;
	else if (n==errSERVO_PAR_TIME_OFF) n=8;
	else n=9; // Demais erros

	irq_Disable();

	static int x;
	while(1) {
		for (x=0;x<n;x++) {
			ledERROR_On();	buzzer_On();	delay_ms(250);
			ledERROR_Off();	buzzer_Off();	delay_ms(250);
		}
		delay_ms(1000);
	}
}

int main(void) {
	nvic_SetIntHandler(showVicError);

	// NÃO USAR UART COM INTERRUPÇÃO PARA O LOG, POIS CONSTANTEMENTE A
  	// POSIÇÃO DOS VETORES DE INTERRUPÇÕES COM O USO DO BOOTLOADER

  	// REGISTRANDO AS ENTRADAS E SAÍDAS PADRÃO AOS SEUS RESPECTIVOS DISPOSTIVOS
	// PORTA PARA CLI DEVE SER COM INTERRUPÇÃO
  	lgetchar_RegisterDev(uart0_GetChar);
	lputchar_RegisterDev(uart0_PutChar);
	ldebug_RegisterDev(uart0_BasicPutChar);
	uart0_Init(115200);

	systime_Init();
	systime_SetIntHandler(app_Tick, 1); // Chamar o a função callsystem a cada 1ms OBS: Levando em consideração o SYSTIME_IRQ_TICK_DIV
	ledError_Init();
	beep_Init();
	gKey_Init(onKeyDown, &onKeyPress, &onKeyUp);	// Anexar os eventos do teclado
	servo_Init();
	lcd_Init(16, 2, LCD_5x8DOTS);
	lcd_printfInit(16, STDIO_DEV1);
	servus_Init(pdOFF);
	ssp1_Init(SSP0_MASTER, SSP0_CPOL_H|SSP0_CPHA_H|SSP0_DSS_8); // inicar o barramento SPI a 400Khz
	joy_Init();

	irq_Enable(); 	// Habilitar interrupções
	app_Init();

	lprintf(CMD_TERMINATOR);
	lprintf(PROGAM_NAME);
	lprintf("ucLibc version "__VERSION CMD_TERMINATOR);

	while (1) {
		prompt_Process();
		app_Process();
		gKey_Process(control.key); // se há tecla pressiona o processo vai chamar os onKeyXXXX
	}

	return (0);
}
